import path from 'path';
import { homeDir } from '$common';

type IdMapper = (index: number) => string;

export class NameGenerator {
  private index: number;

  static create(idMapper: IdMapper): NameGenerator {
    const idGenerator: NameGenerator = new NameGenerator();
    idGenerator.mapIndex = idMapper;
    return idGenerator;
  }

  constructor() {
    this.index = 0;
  }

  public get(): string {
    this.index++;
    if (this.index >= Number.MAX_SAFE_INTEGER - 10) {
      this.index = 1;
    }
    return this.mapIndex(this.index);
  }

  private mapIndex = (index: number): string => {
    return `${index}`;
  };
}

/**
 * **************************
 ├── drivers
 │   └── axisuite
 │       ├── axisuite.exe
 │       └── driver.config.json
 └── jobs
     └── axisuite
         ├── 1
         │   ├──- input.json
         │   ├──- output.json
         │   └──- sim-1.zip
         |   |___ param1.csv
         |   |___ param2.csv
         └── 2
             ├── input.json
             ├── output.json
             └── sim-2.zip
 * **************************/

export class SimulationPath {
  static of = (productName: string, jobId: string) => new SimulationPath(productName, jobId);
  
  private constructor(private productName: string, private jobId: string) { }

  private getProductDir() {
    return path.join(homeDir, 'jobs', this.productName);
  }

  public getJobDir() {
    return path.join(this.getProductDir(), this.jobId);
  }

  public getSimInputFile() {
    return path.join(this.getJobDir(), 'input.json');
  }

  public getSimOutputFile() {
    return path.join(this.getJobDir(), 'output.json');
  }

  public getParameterDir() {
    return path.join(this.getJobDir(), 'parameters');
  }

  public getSimZipFile() {
    return path.join(this.getJobDir(), `sim-${this.productName}.zip`);
  }

  public getSimModelDir() {
    return path.join(this.getJobDir(), 'model');
  }

  public getSimWatchDir() {
    return path.join(this.getSimModelDir(), 'tmp');
  }

  public getParameterFile(filename: string) {
    return path.join(this.getParameterDir(), filename);
  }

  public getSimProcessFile() {
    return path.join(this.getJobDir(), 'process.json');
  }
}